package storage

import (
	"context"
	"WchimeGinSystem/conf"
	"WchimeGinSystem/utils"
	"io"
	"log"
	"net/http"
	"net/url"
	"path/filepath"
	"strings"
	"time"

	"github.com/tencentyun/cos-go-sdk-v5"
)

var CosClientGlobal *CosClient

type CosClient struct {
	Client *cos.Client
}

func (c *CosClient) UploadFile(file io.Reader, path_name string, ContentType string) error {
	var opt *cos.ObjectPutOptions
	if ContentType != "" {
		opt = &cos.ObjectPutOptions{
			ObjectPutHeaderOptions: &cos.ObjectPutHeaderOptions{
				ContentType: MyContentType[ContentType],
			},
		}
	} else {
		opt = &cos.ObjectPutOptions{
			ObjectPutHeaderOptions: &cos.ObjectPutHeaderOptions{
				ContentType: MyContentType["png"],
			},
		}
	}
	// 上传文件到存储桶
	_, err := c.Client.Object.Put(context.Background(), path_name, file, opt)
	if err != nil {
		log.Println("上传文件失败: ", err)
		return err
	}
	return nil
}

func (c *CosClient) GetFile(objectName string) (io.ReadCloser, error) {
	// 下载存储桶中的文件
	resp, err := c.Client.Object.Get(context.Background(), objectName, nil)
	if err != nil {
		log.Println("获取文件失败: ", err)
		return nil, err
	}
	ret_data := resp.Body

	return ret_data, nil
}

// GetPresignedGetObject 返回对象的url地址，有效期时间为expires
func (c *CosClient) GetPresignedGetObject(ak string, sk string, objectName string, expires time.Duration, watermark bool) (string, error) {

	opt := &cos.PresignedURLOptions{
		Query:  &url.Values{},
		Header: &http.Header{},
	}
	// 是否加水印
	if watermark {
		opt.Query.Add("watermark/1/image/aHR0cDovL3RyZW5kLTEzMTMzNDA5OTUuY29zLmFwLWd1YW5nemhvdS5teXFjbG91ZC5jb20vY2Ry5rC05Y2wNC5wbmc/dissolve/50/batch/1/degree/35", "")
	}

	presignedURL, err := c.Client.Object.GetPresignedURL(context.Background(), http.MethodGet, objectName, ak, sk, time.Duration(300)*time.Second, opt)
	if err != nil {
		log.Println("获取文件失败: ", err)
		return "", err
	}

	return presignedURL.String(), nil
}

// 删除对象
func (c *CosClient) RemoveFile(objectName string) error {

	_, err := c.Client.Object.Delete(context.Background(), objectName)
	if err != nil {
		log.Println("删除文件失败: ", err)
		return err
	}

	return nil
}

// ----------------------------------------------------------

// NewCosClient 初始化cos
func NewCosClient() *CosClient {
	// 初始化 COS 客户端

	u, _ := url.Parse(conf.COS_DOMAIN)
	b := &cos.BaseURL{BucketURL: u}

	cos_client := cos.NewClient(b, &http.Client{
		Transport: &cos.AuthorizationTransport{
			SecretID:  conf.COS_SECRET_ID,  // 用户的 SecretId，建议使用子账号密钥，授权遵循最小权限指引，降低使用风险。子账号密钥获取可参考 https://cloud.tencent.com/document/product/598/37140
			SecretKey: conf.COS_SECRET_KEY, // 用户的 SecretKey，建议使用子账号密钥，授权遵循最小权限指引，降低使用风险。子账号密钥获取可参考 https://cloud.tencent.com/document/product/598/37140
			// Expire:    time.Hour,
			// Transport: &debug.DebugRequestTransport{
			// 	RequestHeader:  true,
			// 	RequestBody:    true,
			// 	ResponseHeader: true,
			// 	ResponseBody:   true,
			// },
		},
	})
	client := &CosClient{
		Client: cos_client,
	}
	CosClientGlobal = client
	return CosClientGlobal
}

func COSUpload(file io.Reader, file_name string, forlder_path string, ContentType string) (string, error) {
	name_li := strings.Split(file_name, ".")
	file_type := name_li[len(name_li)-1]
	time_name := utils.GetTimeString()
	new_file_name := time_name + "." + file_type
	put_path := filepath.Join(forlder_path, new_file_name)
	put_path = strings.ReplaceAll(put_path, "\\", "/")

	client := NewCosClient()

	err := client.UploadFile(file, put_path, ContentType)

	return put_path, err
}

func COSGetFile(file_name string) (io.ReadCloser, error) {
	client := NewCosClient()
	return client.GetFile(file_name)
}

func COSGetURL(file_name string, watermark bool) (string, error) {
	client := NewCosClient()
	return client.GetPresignedGetObject(conf.COS_SECRET_ID, conf.COS_SECRET_KEY, file_name, time.Duration(300)*time.Second, watermark)

}

func COSDelFile(file_name string) error {
	client := NewCosClient()

	return client.RemoveFile(file_name)
}
